package com.unicom_ng.rfid;

import java.util.HashSet;
import java.util.Set;
import java.util.Iterator;

import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Build;
import android.widget.Toast;
import android.os.Handler;
import android.os.Message;
import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.rfid.rxobserver.bean.RXInventoryTag;
import java.util.Map;
import android.util.Log;
import java.util.HashMap;
import android.provider.Settings;

import androidx.annotation.RequiresApi;

import com.facebook.react.bridge.Arguments;
import com.facebook.react.bridge.WritableMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.bridge.WritableNativeArray;
import com.facebook.react.modules.core.DeviceEventManagerModule;

import static android.media.RingtoneManager.TYPE_NOTIFICATION;

public class RfidModule extends ReactContextBaseJavaModule implements RfidUtil.RFIDInterface {
  private final static int SCAN_OVER = 2;
  private final static int SCAN_FAIL = 0;
  private final static int SCAN_REVEICE = 1;
  private final static String UNINIT_STATE="uninit"; // 未初始化
  private final static String INIT_STATE="init"; // 已初始化
  private final static String DESTORY_STATE="destory"; // 已释放
  private static final String DURATION_SHORT_KEY = "SHORT";
  private static final String DURATION_LONG_KEY = "LONG";
  private static RfidUtil rfidUtil;
  ReactApplicationContext reactContext;
  private String[] rfidType = new String[0];
  private Map<String,RXInventoryTag> rfidSet = new HashMap<>();
  private final static String FIND_HANDLE_KEY="find";
  private final static String SCAN_HANDLE_KEY="scan";
  private String currentHandleType = SCAN_HANDLE_KEY;
  private String currentFindRfid = null;
  private BeepManager been;
  private String state = UNINIT_STATE; // rfid模块状态
  Uri notification = RingtoneManager.getDefaultUri(TYPE_NOTIFICATION);
  Ringtone r;

  public RfidModule(ReactApplicationContext reactContext) {
    super(reactContext);
    this.reactContext=reactContext;
    Log.i("test","进入RfidModule构造函数");
    if(rfidUtil==null){
      rfidUtil = RfidUtil.getInstance();
      Log.i("test","rfidUtil初始化完成,在RfidModule构造函数");
    }
  }

  @Override
  public String getName() {
    return "RfidModule";
  }

  @ReactMethod(isBlockingSynchronousMethod = true)
  public String getState() {
    return this.state;
  }

  @ReactMethod
  public void init() {
    if(rfidUtil==null){
      rfidUtil = RfidUtil.getInstance();
      Log.i("test","rfidUtil初始化完成,在init构造函数");
    }
    rfidUtil.init();
    rfidUtil.setOnReceive(this);
    rfidUtil.up();
    if(been==null){
      been=new BeepManager(reactContext);
    }

    this.state=INIT_STATE;
  }

  public static void create(){
    if(rfidUtil==null){
      rfidUtil = RfidUtil.getInstance();
      Log.i("test","rfidUtil初始化完成,在create构造函数");
    }
    rfidUtil.init();
  }

  public static void release(){
    rfidUtil.onDestory();
  }

  @ReactMethod
  public void scan() {
    currentHandleType=SCAN_HANDLE_KEY;
    rfidUtil.command();
  }

  @ReactMethod
  public void find(String rfid) {
    this.currentFindRfid=rfid;
    currentHandleType=FIND_HANDLE_KEY;
    rfidUtil.command();
  }

  @ReactMethod
  public void destory() {
    rfidUtil.down();
    rfidUtil.onDestory();
    this.state=UNINIT_STATE;
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @ReactMethod
  public void beep(float volume) {
    try {
      this.been.playBeepSoundAndVibrate(volume,volume);
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  @Override
  public void fail() {
    rfidSet.clear();
  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  @Override
  public void over() {
    System.out.println(" ======"+this.currentHandleType);
    switch (this.currentHandleType){
      case SCAN_HANDLE_KEY:
        scanHandle();
        break;
      case FIND_HANDLE_KEY:
        findHandle();
        break;
    }

  }

  @RequiresApi(api = Build.VERSION_CODES.P)
  private void findHandle(){
    System.out.println("this.currentFindRfid="+this.currentFindRfid);
    Iterator<String> it = rfidSet.keySet().iterator();
    while (it.hasNext()) {
      String rfid = it.next();
      System.out.println("tag:"+rfid);
    }
    if(this.currentFindRfid==null || "".equals(this.currentFindRfid) || rfidSet.containsKey(this.currentFindRfid)==false) return;
    RXInventoryTag tag = this.rfidSet.get(this.currentFindRfid);
    rfidSet.clear();
    System.out.println("rssi=" + tag.strRSSI);
    System.out.println("btAntId=" + tag.btAntId);
    System.out.println("strPC=" + tag.strPC);
    System.out.println("strCRC=" + tag.strCRC);
    System.out.println("strFreq=" + tag.strFreq);
    System.out.println("============================");

    try{
      float volumn = Math.min(Float.valueOf(tag.strRSSI),70.0f)/70.0f;
      this.beep(volumn);
    } catch (NumberFormatException e) {
      e.printStackTrace();
    }

  }

  private void scanHandle(){
    if(rfidSet.size()==0) return;
    WritableArray writableArray = new WritableNativeArray();
    Iterator<String> it = rfidSet.keySet().iterator();
    while (it.hasNext()) {
      String rfid = it.next();
      writableArray.pushString(rfid);
    }
    rfidSet.clear();
    this.beep(1F);
    sendEvent(this.reactContext, "onRfidReveice", writableArray);
  }

  @Override
  public void onReveice(RXInventoryTag tag) {
    String rfid=tag.strEPC.replace(" ", "");
    // if(rfid.length() > 8){
    //   rfidSet.put(rfid.substring(rfid.length() - 8,rfid.length()),tag);
    // }else{
    //   rfidSet.put(rfid,tag);
    // }
    // 121101AA
    if(rfid.length() > 8){
      if(rfid.contains("AA")){
        rfid = rfid.replace("AA","-");
      }else{
        rfid = rfid.substring(rfid.length() - 8,rfid.length());
      }
    }
    rfidSet.put(rfid,tag);
  }

  //定义发送事件的函数
  public void sendEvent(ReactContext reactContext, String eventName, WritableArray params)
  {
    reactContext
              .getJSModule(DeviceEventManagerModule.RCTDeviceEventEmitter.class)
              .emit(eventName,params);
  }
}